// Copyright (c) 2010 Omer Goshen
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#ifndef __EditorState_H__
#define __EditorState_H__

#include "MudBath.h"
#include "App.h"
#include "GameState.h" // Base Class

#include "utils/ViewportGrid.h"

using namespace Ogre;

class App;
class Console;
class HUD;

class SelectionBuffer;
class DeferredShadingSystem;

class GenericCamera;
class FlyCamera;
class ChaseCamera;
class OrbitCamera;

class InputManager;

class GameState;
class EditorState;

class TransformWidget;

class SelectionRectangle;

class EditorState : public GameState
{
public:
	void enter();
	void exit();

	void pause();
	void resume();

	bool frameStarted(const Ogre::FrameEvent& evt);
	bool frameEnded(const Ogre::FrameEvent& evt);

	void keyPressed( const OIS::KeyEvent &e );
	void keyReleased( const OIS::KeyEvent &e );

	void mouseMoved( const OIS::MouseEvent &e );
	void mousePressed( const OIS::MouseEvent &e, OIS::MouseButtonID id );
	void mouseReleased( const OIS::MouseEvent &e, OIS::MouseButtonID id );

	bool OverlayHandler(const CEGUI::EventArgs& args);

//	CEGUI::OgreRenderer& mRenderer;
	CEGUI::GeometryBuffer* mFPSGeometry;
	Ogre::String mDebugText;
	Ogre::String mDebugText2;
    Real mLastUpdate ;

	static EditorState* getInstance() {	return &mEditorState; }

	inline void setActive(bool s) { active = s; }

	bool mFixedCamera;

	void initGui();
	void createScene();
	void createCameras();
	void clearScene();

	void onObjectSelected();

//	sigc::signal<void> onObjectSelected;	

protected:
	bool active;

	App* 					app;
	Ogre::Root* 			mRoot;
	Ogre::RenderWindow* 	mWindow;

	Camera* 				mCamera;
	Viewport* 				mViewport;
	SceneManager* 			mSceneMgr;
	DeferredShadingSystem* 	mSystem;

	SceneNode* 				mCameraNode;
	FlyCamera* 				flyCam;
	OrbitCamera* 			orbitCam;

	BaseGameObject* 		mOldObject;
	BaseGameObject*			mCurrentObject;
	SceneNode*		 		mCurrentNode;

	//{{{ Selection
	GameObjectGroup 		mSelectedObjects;
	SelectionBuffer* 		mSelectionBuffer;
    
	PlaneBoundedVolumeListSceneQuery *mVolQuery;
    std::list<MovableObject*> mSelected;
    SelectionRectangle *mRect;
	Vector2 mStart;
	Vector2 mStop;
	bool	mSelecting;
	//}}}
	
	HUD* 			 		mHUD;
	TransformWidget* 		mTFW;
	Ogre::ViewportGrid* 	mViewportGrid;

	bool mExitGame;

private:
	EditorState() {}
	static EditorState mEditorState;
};

#endif
